Design Pattern

Gabriele Zarcone

8 maggio 2018

UML

FONTE

Pattern Creazionali

Factory

Abstract Factory

Singleton

Pattern Strutturali

Adapter

FONTE

Intento

Permette a due classi di lavorare insieme nonostante abbiano delle interfacce incompatibili. Converte l’interfaccia di una classe in un interfaccia utile al cliente.

Avvolge una classe esistenza ad una nuova interfaccia.

Se voglio utilizzare un componente non sviluppato da me questo avrà una certa interfaccia per interfacciarsi con l’esterno. Io probabilmente ho bisogno di un altro tipo di interfaccia per collegarlo al mio sistema.

Discussione

L’adapter crea una astrazione intermedia che traduce la classe da utilizzare in maniera comprensibile al nuovo sistema.

Il cliente richiama i metodi dell’oggetto Adapter e la chaimata viene reindirizzata all’Adaptee. Può essere creata sia con AGGREGAZIONE che con EREDITARIETA’

L’adapter avvolge una classe presistente e mi restituisce una traduzione di quest’ultima.

Struttura

Come implementarlo

  1. Identifica i soggetti: identificare qual’è il Client e chi è l’Adaptee.

  2. Identifica l’interfaccia: capire qual’è l’interfaccia di cui ha bisogno il Client.

  3. Creare la classe Adapter che implementa l’interfaccia e i suoi metodi chiamando i metodi dell’Adaptee

  4. Per farlo la classe Adapter deve avere il metodo della classe Adaptee

Differenze con altri pattern


Composite

FONTE

Intento

Serve per comporre oggetti dentro a delle strutture ad albero. Permette così di trattare insiemi di oggetti dello stesso tipo come se fossero un oggetto singolo.

Puo essere ricorsivo e quindi una Directory contiene Entità ma ogni Entità può essere una Directory.

La gestione di una Directory e di una Entità sarà sicuramente diversa, ma con il composite rendiamo questa differenza trasparente al Client che potrà trattare il gruppo come il singolo.

Discussione

Creo una classe astratta Component che specifica il comportamento che voglio implementare (sia che l’oggetto sia singolo o un gruppo di oggetti). Le classi che rappresentano l’oggetto singolo(Leaf) e il gruppo(Composite) saranno figli della classe Component.

L’oggetto Composite può poi associare un altro oggetto Component.

Il pattern va quindi usato ogni volta che:

Ho un Composite che contienen un Component che può essere a sua volta un component.

Quando ho bisgno di una struttura come quella delle cartelle sul PC

Struttura

Come implementarlo

  1. Assicurarsi che si vuole rappresentare una intera relazione gerarchica.

  2. Considerando il “Contenitori che contengono contenuti i quali a loro volta possono essere contenitori” e dividere i contenuti dai contenitori.

  3. Creare l’interfaccia che rende intercambiabile i contenuti con i contenitori. Che specifichi il comportamento che deve essere esercitato in modo uguale su Container o Continee

  4. Container e Continee sono in una relazione is a con l’interfaccia

  5. I Container sono in una relazione has a 1aMOLTI con l’interfaccia

  6. Le classi di contenitori sfruttano il polimorfismo per delegare ai propri oggetti contenitori.

  7. I metodi addChild() e removeChild() avrebbe più senso averli nella classe Component se vogliamo la trasparenza, quindi trattare uniformamente Leaf e Composite. Vengono invece inseriti nella classe Component. Sacrificando la trasparenza per la sicurezza (spiegato nelle Osservazioni)

Differenze con altri pattern

Considerazioni

Il punto principale del pettern Composite è quello di poter trattare il gruppo (COmposite) come se fosse un singolo (Leaf). Si può ottenere similmente anche con un Iterator ma sarebbe una forzatura dello stesso.

Grazie al Composite il client può effettuare operazioni su un oggetto senza che sappia che quell’oggetto è composto da più oggetti.

Può però trattare un insieme di oggetti eterogeneo in maniera atomica (o trasparente) solamente se la gestione dei figli viene gestita dall’interfaccia Component così che Leaf e Composite siano trattabili allo stesso modo. Però questo porta ad un problema di Sicurezza in quanto l’utente vede solo l’interfaccia Component e in questo modo si permettee al client di creare o cancellare figli. Quindi per aumentare la sicurezza si preferisce lasciare la implementazione dei metodi per la gestione dei figli alla classe Composite. Sacrificando la trasparenza per la sicurezza. Non ho più trasparenza perchè ora Composite può avere diverse interfacce

…da completare…


Decorator

FONTE

Intento

Vuole aggiungere delle funzionalità ad un ogggetto anche dinamicamente e lo fa senza ricorrere all’utilizzo di sottoclassi. Un componente può essere abbellito da un altro avvolgendolo ricorsivamente.

Incarta un regalo, mettilo in una scatola e quindi incarta anche quella

Voglio quindi aggiungere un comportamento o uno stato in run-time. Però per farlo non posso usare la ereditarietà perchè non è dinamica ma statica.

Discussione

Se lo facessimo con un gerarchia di ereditarietà non diamo all’utente la possibilità di scegliere lui la combinazione di abbellimenti da mettere alla classe ma sarebbe forzato ad usare solamente uno dei figli. Se volessimo permettere tutte le combinazioni avremmo il numero di classi che crescerebbe esponenzioalmente. La struttura definità dal pattern è dunque essenziale.

Risolvo dunque il problema incapsulando l’oggetto base da cui partiamo (ConcreteComponent) con un interfaccia involucro (Component). Dunque sia il Decorator che il ConcreteComponent implementano entrambi l’interfaccia. E attraverso la composizione ricorsiva posso aggiungere un numero indefinito di decorator.

Bisogna fare attenzione che il Pattern Decorator non modifica l’interfaccia vista dal cliente aggiungendo dei metodi all’interfaccia stessa, ma ….

Le decorazioni non cambiano l’abero di natale il quale rimane un albero anche con le decorazioni

Struttura

Come implementarlo

  1. Il contesto deve essere rappresentato da un unico componente base non opzionale che può essere arricchito da più abbellimenti.

  2. Creo un interfaccia che rende tutte queste classi intercambiabili

  3. Creo un altra interfaccia che supporti tutte le

Differenze con altri pattern

Considerazioni


Facade

FONTE

Intento

Se ho un complesso sistema di interfacce e di classi e voglio creare una interfaccia che comunichi con il client e sappia gestire la sottostruttura più complessa. Così che il client veda solatanto un interfaccia semplice e non una struttura enorme.

Discussione

Con un facade posso diminuire la curva di apprendimento necessaria al client per interagire con il mio sistema, ma allo stesso punto potrei limitare l’accesso a funzionalità del mio sistema utili ad un “power user”.

Struttura

Le diverse parti del sottsistema non interagiscono tra loro direttamnte ma la loro interazione è gestita dall’interfaccia del Facade

Come implementarlo

Differenze con altri pattern

Considerazioni


Flyweigh


Pattern Comportamentali

Chain of Reponsability


Command


Iterator


Observer


State


Strategy